if exists("b:__XPT_XPT_XPT_VIM__")
  finish
endif
let b:__XPT_XPT_XPT_VIM__ = 1

" containers
let [s:f, s:v] = XPTcontainer()

" constant definition
call extend(s:v, {'$TRUE': '1', '$FALSE': '0', '$NULL': '', '$UNDEFINED': ''})
" call XPTemplatePriority('sub')

" common.xpt.vim must be included.
" inclusion
XPTinclude
      \ _common/common

" ========================= Function and Variables =============================
fun! s:f.xptHeader() "{{{
  let symbol = expand("%:p")
  let symbol = matchstr(symbol, '[/\\]ftplugin[/\\]\zs.*')
  let symbol = substitute(symbol, '/', '_', 'g')
  let symbol = substitute(symbol, '\.', '_', 'g')
  let symbol = substitute(symbol, '\\', '_', 'g')
  let symbol = substitute(symbol, '.', '\u&', 'g')
  
  return '__'.symbol.'__'
endfunction "}}}

fun! s:f.popUpXptDir() "{{{
  " ../* referencing to current directory, not where this script is .
  " Ok i tought everyone develop xpt plugin work under ftplugin dir =))
  " let list = split(substitute(expand("../*"),"\.\.[\\/]",'','g'), "\n")

  " all directories
  let ftpDir = globpath(&rtp, "ftplugin/*/*.xpt.vim")
  " remove path header 
  let ftpDir = substitute(ftpDir, '\%(^\|\n\)\zs.\{-}[/\\]ftplugin[/\\]', '', 'g')
  " remove files 
  let ftpDir = substitute(ftpDir, '[/\\].\{-}\.xpt\.vim', '', 'g')

  let list = split(ftpDir, "\n")
  return list
endfunction "}}}

" xp added 
fun! s:f.popUpXptFileName() "{{{
  " value of last item  
  let pathPlugin = self.R('fileDir')
  let pathPlugin = matchstr(pathPlugin, '\w\+\ze/')

  " fetch all .xpt.vim files
  let snippets = globpath(&rtp,  "ftplugin/" . pathPlugin ."/*.xpt.vim")

  " remove leading '\' and '/' 
  let snippets = substitute(snippets, '\%(^\|\n\)\zs.\{-}[/\\]ftplugin[/\\]' . pathPlugin . '[/\\]', '', 'g')

  " remove '.xpt.vim' 
  let snippets = substitute(snippets, '\V.xpt.vim\ze\%(\n\|\$\)', '', 'g')

  let list = split(snippets, "\n")
  if (len(list) == 1)
    return list[0]
  else
    return list
  endif
endfunction "}}}

fun! s:f.ChooseDefault(def, ...) "{{{
  "modificata per aggiungere i bordi"
  let edges = self.ItemEdges()
  let str = self.V()
  if (str == '')
    return a:def
  elseif (str == (edges[0] . edges[1]))
    return edges[0] . a:def . edges[1]
  else
    if (a:0 > 0)
      return edges[0] . a:1 . edges[1]
    else
      return edges[0] . str . edges[1]
    endif
  endif
endfunction "}}}

fun! s:f.ExtendIfNotEmpty(start, end, ...) "{{{
  let str = self.V()
  let edges = self.ItemEdges()
  
  if (str == '')
    return ''
  elseif (str == (edges[0] . edges[1]))
    return ''    
  else
    if (a:0 > 0)
      let str = a:1
    endif
    return a:start . str . a:end
  endif
endfunction "}}}

fun! s:f.TriggerPost(...) "{{{
  let tr = self.V()
  if (tr != '')
    let list = XPTgetAllTemplates()
    if (has_key(list, tr))
      return list[tr]['tmpl']
    else
      return tr
    endif
  elseif (a:0 > 0)
    let list = XPTgetAllTemplates()
    return list[a:1]['tmpl']
  endif  
endfunction "}}}

" ================================= Snippets ===================================
XPTemplateDef

XPT tmpl hint=call\ XPTemplate(\ ...
XSET hint...|post= hint=`hint^
XSET hint|post=SV(" ", '\\ ')
XSET xset...|post=`xset^\n`xset...^
XSET xset=Trigger('xset')
\XPT `name^`hint...^
`xset...^ 
`cursor^

XPT xset hint=XSET\ ...
XSET attrib=Choose(['|def', '|post'])
\XSET `tag^`attrib^=`value^

XPT tmpl_ hint=call\ XPTemplate(\ ..,\ SEL\ ...
call XPTemplate('`name^', ['`wrapped^'])

XPT incItem hint=\\ filedir/filename
XSET item...|post=`fileDir^
XSET fileDir=popUpXptDir()
XSET fileDir|post=ExtendIfNotEmpty('\ ', '/`fileName^\n`item...^')
XSET fileName=popUpXptFileName()
XSET fileName|post=ChooseDefault(popUpXptFileName()[0])
`item...^


" xp added 
" incitem is better...default value and plus '\ ' is added just if needed)
XPT incItem2 hint=\\ filedir/filename
XSET item...|post=\\ `fileDir^
XSET fileDir=popUpXptDir()
XSET fileDir|post=ExtendIfNotEmpty('', '/`fileName^\n`item...^')
XSET fileName=popUpXptFileName()
`item...^

XPT inc hint=XPTinclude\ ...
XSET include...|post=XPTinclude\n`incItem^
XSET incItem=Trigger('incItem')
`include...^
`cursor^

XPT once hint=if\ exists\ finish\ let\ b...
if exists("b:`i^xptHeader()^")
    finish
endif
let b:`i^ = 1

XPT container hint=let\ [s:f,\ s:v]\ =...
let [s:f, s:v] = XPTcontainer()

XPT funct hint=fun!\ s:f.name...
XSET arg..|post=ExpandIfNotEmpty(', ', 'arg..')
fun! s:f.`name^(`arg..^) "{{{
  `body^^
endfunction "}}}
`cursor^

XPT const hint=XPTvar\ ...
XSET name|post=ExtendIfNotEmpty('XPTvar $', ' `value^', SV('\([a-z]\)', '\u\1','g'))
`name^ 

XPT xpt hint=start\ template\ to\ write\ template
XSET include...|post=`inc^
XSET inc|def=Trigger('inc')
XSET const...|post=`const^\n`const...^
XSET const|def=Trigger('const')
XSET tmpl...|post=`tmpl^\n`tmpl...^
XSET tmpl=Trigger('tmpl')
XSET functions...|post=`funct^\n`functions...^
XSET funct=Trigger('funct')
XSET priority=Choose(['all', 'spec', 'like', 'lang', 'sub', 'personal'])
XSET priority|post=ChooseDefault('lang')
XPTemplate priority=`priority^
if exists("b:`i^xptHeader()^") 
  finish 
endif
let b:`i^ = 1 

" inclusion
`include...^

" ========================= Function and Variables =============================
" containers
let [s:f, s:v] = XPTcontainer()

" constant definition
XPTvar $TRUE 1
XPTvar $FALSE 0
XPTvar $NULL ''
XPTVar $UNDEFINED ''
XPTvar $BRACKETSTYLE "\n"
`const...^

" function definition
`functions...^

" ================================= Snippets ===================================
XPTemplateDef

`tmpl...^
`cursor^
